package 多线程;

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : K k
 * @date : 10:52 2020/8/11]
 * ReentrantLock和condition应用 消费者问题
 */
public class ProduceAndConsumerFlag {
    private ReentrantLock lock = new ReentrantLock();
    private volatile boolean flag = false;
    private Condition condition = lock.newCondition();

    int[] product = new int[10];
    private int count=0; //产品数量
    Random random=new Random(10);

    public void produce() {

        try {
            lock.lock();
            while (flag) {
                //若生产够10个则阻塞线程，让消费者消费
                condition.await();
            }
            System.out.println(Thread.currentThread().getName()+"----生产------");
            product[count]= random.nextInt();
            count++;
            if (count==product.length){
                flag=true;
            }
            System.out.println("number: " + count);
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void consumer() {
        try {
            lock.lock();
            while (!flag) {
                //若生产够10个则阻塞线程，让消费者消费
                condition.await();
            }
            System.out.println(Thread.currentThread().getName()+"----消费------");
            System.out.println("number: " + count);
            count--;
            if (count==0){
                flag=false;
            }
            condition.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ProduceAndConsumerFlag service=new ProduceAndConsumerFlag();
        Thread thread1 = new Thread(new producer1(service),"生产者");
        consumer1 consumer1 = new consumer1(service);
        Thread thread2 = new Thread(consumer1,"消费者1");
        Thread thread3 = new Thread(consumer1,"消费者2");

        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.execute(thread1);
        executorService.execute(thread2);
        executorService.execute(thread3);
    }

}

class producer1 implements Runnable{
    private ProduceAndConsumerFlag service;
    public producer1(ProduceAndConsumerFlag service){
        this.service=service;
    }

    @Override
    public void run() {
        for (int i=0; i<200; i++){
            service.produce();
        }
    }
}

class consumer1 implements  Runnable{

    private ProduceAndConsumerFlag service;

    public consumer1(ProduceAndConsumerFlag service){
        this.service=service;
    }

    @Override
    public void run() {
        for (int i=0; i<100; i++){
            service.consumer();
        }
    }
}